#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//宏定义
#define MAX_NAME_LEN 20  // 最大姓名长度
#define MAX_STUDENTS 100  // 最大学生数量
#define FILENAME "students_data.txt"  // 数据文件名
#define DEBUG_MODE 1 // 1表示开启调试模式，0表示关闭

// 学生结构体定义
typedef struct {
    int id;
    char name[MAX_NAME_LEN];
    float score;
} Student;

//全局函数声明
void addStudent(Student students[], int *count);
void displayAll(Student students[],int count);
int searchStudent(Student students[],int count,int targetId);
void modifyStudent(Student students[],int count);
void deleteStudent(Student students[], int *count);
void displayStudent(Student *s) ;



int main(){
    Student students[MAX_STUDENTS];
    int count =0;

    int choice;

    FILE *fp = fopen(FILENAME, "r");
    if(fp != NULL){
        while(fscanf(fp, "%d %s %f",&students[count].id, students[count].name, &students[count].score) == 3) {
            count++;
            if(count >=MAX_STUDENTS){
                printf("Students number out of max, some datas are not read in");
                break;
            }

        }
        printf("read %d students xinxi.\n",count);
        fclose(fp);
        
    } else {
        printf("未找到该文件,将创造新文件.\n");
    }


    while (1)
    {
        printf("\n================= 学生管理系统 ================\n");
        printf("1. 添加学生\n");
        printf("2. 显示所有学生\n");
        printf("3. 查找学生\n");
        printf("4. 修改学生信息\n");
        printf("5. 删除学生\n");
    
        printf("10. 退出\n");
        printf("请选择：");
        scanf("%d",&choice);

        switch(choice){
            case 1:
                addStudent(students,&count);
                break;
            case 2:
                displayAll(students,count);
                break;
            case 3: {
                int targetId;
                printf("请输入要查找的学生id：");
                scanf("%d", &targetId);
                int index = searchStudent(students, count, targetId);
                if (index != -1) {
                    displayStudent(&students[index]);
                } else {
                    printf("未找到该学生。\n");
                }
            }
                 
                break;
            case 4:
                modifyStudent(students,count);
                break;
            
            case 5:
                deleteStudent(students, &count);
                break;
            case 10:
                fp = fopen(FILENAME, "w");
                if( fp != NULL){
                    for(int i=0;i<count;i++){
                        fprintf(fp, "%d %s %.2f\n", students[i].id, students[i].name, students[i].score );

                    }
                    fclose(fp);
                    printf("学生数据已保存到 %s\n", FILENAME);
                }else {

                    printf("Error happened!!!");
                }
                printf("退出系统。\n");
                exit(0);
                break;
            default:
                printf("无效的选择，请重新输入\n");
            
        }
    }
    
}

void addStudent(Student students[],int *count){
    if(*count >= MAX_STUDENTS){
        printf("学生数量已达上限，无法添加更多学生。\n");
        return;
    }

    Student *newStudent = &students[*count];
    printf("请输入学生id：\n");
    scanf("%d", &newStudent->id);

    while (getchar() != '\n')
    
    printf("请输入学生姓名：\n");
    fgets(newStudent->name, MAX_NAME_LEN, stdin);

    //一处fgets读取的时候自带的换行符
    newStudent->name[strcspn(newStudent->name, "\n")] = '\0';

    printf("请输入学生成绩：\n");
    scanf("%f", &newStudent->score);

    //学生数量+1
    (*count)++;
    

    printf("学生添加成功！\n");
}

void displayAll(Student students[], int count) {
    if (count == 0) {
        printf("系统中还没有学生记录！\n");
        return;
    }
    
    printf("\n%-10s %-20s %s\n", "ID", "姓名", "成绩");
    printf("=================================\n");
    
    // 使用指针遍历数组
    Student *ptr = students;
    for (int i = 0; i < count; i++, ptr++) {
        printf("%-10d %-20s %.2f\n", ptr->id, ptr->name, ptr->score);
    }
}

int searchStudent(Student students[],int count, int targetId){
    for(int i=0;i<count; i++){
        if(students[i].id  == targetId){
            return i;
        } 
    }
    return -1;
}

void displayStudent(Student *s) {
    printf("\n===== 学生详情 =====\n");
    printf("学号: %d\n姓名: %s\n成绩: %.2f\n", s->id, s->name, s->score);
}

void modifyStudent(Student students[],int count ){
    int targetId;
    printf("请输入要修改的学生id：");
    scanf("%d", &targetId);

    int index = searchStudent(students, count, targetId);
    if (index == -1) {
        printf("未找到该学生。\n");
        return;
    }

    printf("===== 修改学生信息 =====\n");
    displayStudent(&students[index]);
    printf("请输入新的学生姓名：\n");
    getchar(); // 清除输入缓冲区的换行符

    char newName[MAX_NAME_LEN];
    if(fgets(newName, MAX_NAME_LEN, stdin) != NULL) {
        newName[strcspn(newName, "\n")] = '\0'; // 移除换行符
        strncpy(students[index].name, newName, MAX_NAME_LEN);
    }

    printf("请输入新的学生成绩(输入-1保持原值)：\n");
    float newScore;

    if(scanf("%f", &newScore) == 1 && newScore >= 0) {
        students[index].score = newScore;
    }

    printf("学生信息修改成功！\n");
    displayStudent(&students[index]);
}

void deleteStudent(Student students[], int *count) {
    int targetId;
    printf("请输入要删除的学生id：");
    scanf("%d", &targetId);

    int index = searchStudent(students, *count, targetId);
    if (index == -1) {
        printf("未找到该学生。\n");
        return;
    }

    // 将后续学生前移覆盖
    for (int i = index; i < (*count) - 1; i++) {
        students[i] = students[i + 1];
    }
    (*count)--; // 学生数量减1

    printf("学生删除成功！\n");
}